import { EventConst } from "../const/Const";
import { MSG, VIDEO_STATUS } from "../const/MSG";
import eventUtil from "../framework/modules/eventUtil";
import { httpUtil } from "../framework/modules/httpUtil";
import nativeAdResult from "../model/nativeAdResult";
import Common from "../utils/Common";
import { Debug } from "../utils/Debug";
import { BannerOptions } from "./BannerOptions";
import { CustomOptions } from "./CustomOptions";
import NativeOptions from "./NativeOptions";
import { NativeSize } from "./NativeSize";
import { platformConf } from "./platformConf";
import PlatformModule from "./PlatformModule";
import { platformUtil } from "./platformUtil";

export default class VIVOModule extends PlatformModule {

    public platformName: string = "qg";
    public appSid: string = "";
    public mBannerWidth: number = 1080;
    public mBannerHeight: number = 96;


    private interLoadedShow: boolean = false;
    constructor() {
        super();
        this._regisiterWXCallback();
        this.initAdService();
    }

    private initAdService() {
        // this.initBanner();
        // this.initInter();
        // httpUtil.getAllConfig(res => {
        //     for (let k in Common.config) {
        //         if (res && res.hasOwnProperty(k) && "version" != k) {
        //             Common.config[k] = res[k]
        //         }
        //     }

        // })
        // this.prepareNative();
        eventUtil.on(EventConst.ON_PLATFORM_SHOW, this, this.onAppShow)
    }


    public supportVersion(version: string | number) {
        let oppoSys = this.getSystemInfoSync();
        return oppoSys.platformVersionCode >= version
    }



    /**
     * 游戏登录
     * @param callback 
     * @param fail 
     */
    // public login(callback?: Function, fail?: Function) {

    //     httpUtil.getAllConfig(res => {

    //     });

    //     let self = this;

    //     let userToken = dataUtil.getToken();
    //     if (userToken) {
    //         self.getUserToken("", userToken, callback)
    //     }
    //     else {
    //         if (!this.supportVersion(1040)) {
    //             if (Common.isFunction(callback))
    //                 callback({})
    //             return;
    //         }
    //         window[this.platformName].login({
    //             success: (res) => {
    //                 if (res.code) {
    //                     //发起网络请求
    //                     self.getUserToken(res.code, "", callback)
    //                 } else {
    //                     if (Common.isFunction(callback))
    //                         callback({})
    //                 }
    //             },
    //             fail: (res) => {
    //                 if (Common.isFunction(callback))
    //                     callback({})
    //             }
    //         })
    //     }
    // }

    /**
     * 
     * @param code 
     * @param user_id 
     * @param callback 
     */
    // private getUserToken(code, user_id, callback?) {


    //     if (!this.supportVersion(1050)) {
    //         if (Common.isFunction(callback))
    //             callback({});
    //         return;
    //     }
    //     let options = window[this.platformName].getLaunchOptionsSync();



    //     let channel_id = options.query && options.query.channel_id ? options.query.channel_id : "0";
    //     let channel_appid = options.referrerInfo && options.referrerInfo.appId ? options.referrerInfo.appId : "0";

    //     dataUtil.setChannelAppId(channel_appid);
    //     dataUtil.setChannelId(channel_id);

    //     if (window[this.platformName] && window[this.platformName].aldSendEvent) {
    //         window[this.platformName].aldSendEvent("来源", {
    //             origin: options.referrerInfo ? options.referrerInfo.appId : '未知',
    //             path: options.query.from || 0
    //         })
    //     }

    //     httpUtil.request(`${this.baseUrl}api/channel/login.html`, {
    //         appid: platformUtil.currentPlatform.moosnowConfig.moosnowAppId,
    //         code: code,
    //         user_id: user_id,
    //         channel_id: channel_id,
    //         channel_appid: channel_appid
    //     }, "POST", (respone) => {
    //         if (respone.code == 0 && respone.data && respone.data.user_id) {
    //             dataUtil.setToken(respone.data.user_id);
    //         }
    //         if (Common.isFunction(callback))
    //             callback(respone)
    //     }, () => {
    //         //如果出错，不影响游戏
    //         if (Common.isFunction(callback))
    //             callback({})
    //     });
    // }




    public onBannerError(err: any) {
        console.warn('banner___error:', err.errCode, ' msg ', err.errMsg);
    }


    private mShowTime: number = null!;
    private mMinInterval: number = 10
    public _createBannerAd() {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("createBannerAd")) return;
        var win = this.getWindow();
        let nowTime = Date.now();
        if (!this.mShowTime)
            this.mShowTime = nowTime;
        else if (this.mShowTime && (nowTime - this.mShowTime <= this.mMinInterval * 1000)) {
            Debug.log(`banner创建太频繁了 ${this.mMinInterval}秒内只能显示一次`);
            return;
        }
        this.mShowTime = Date.now();
        this.bannerOption.Width = this.mBannerWidth;
        this.bannerOption.Height = this.mBannerHeight;
        let style = this.bannerOption.getBannerStyle(this.getSystemInfoSync());
        let banner = win[this.platformName].createBannerAd({
            posId: this.getBannerId(),
            style: style
        });
        banner.onSize(this._onBannerResize.bind(this))
        return banner;
    }

    private getNotchHeight() {
        let retVal = 0;
        var win = this.getWindow();
        if (win[this.platformName].getNotchHeightSync)
            retVal = win[this.platformName].getNotchHeightSync().height;
        return retVal;
    }

    public _onBannerResize(size: any) {
        this.mBannerHeight = size.realHeight
        this.mBannerWidth = size.realWidth
        // let style = this._getBannerPosition();
        // this.mBannerAd.style.left = style.left;
        // this.mBannerAd.style.top = style.top;
        // this.mBannerAd.style.width = size.realWidth;
        // this.mBannerAd.style.height = size.realHeight;
        Debug.log('onSize callback  ', size)
    }


    public _onBannerClose() {
        Debug.log('banner 已关闭 ')
    }

    public _onBannerHide() {
        Debug.log('banner 已隐藏 ')
    }


    /**
      * 显示平台的banner广告
      * @param remoteOn 是否被后台开关控制 默认 true，误触的地方传 true  普通的地方传 false
      * @param callback 点击回调
      * @param position banner的位置，默认底部
      * @param style 自定义样式
      */
    public showBanner(option: BannerOptions) {
        this.bannerOption = option;

        this.isBannerShow = true;
        if (!this.checkWindow()) return;
        this._showBanner();
    }

    private _showBanner() {
        if (this.mBannerAd && this.mBannerAd.hide) {
            this.mBannerAd.hide();
            this.mBannerAd.offSize();
            this.mBannerAd.destroy()
            this.mBannerAd = null;
        }
        this.mBannerAd = this._createBannerAd();
        if (!(this.mBannerAd && this.mBannerAd.show))
            return;
        let adshow = this.mBannerAd.show();
        adshow && adshow.then(() => {
            Debug.log("banner广告展示成功");
        }).catch((err: any) => {

            switch (err.code) {
                case 30003:
                    Debug.log("新用户1天内不能曝光Banner，请将手机时间调整为1天后，退出游戏重新进入")
                    break;
                case 30009:
                    Debug.log("10秒内调用广告次数超过1次，10秒后再调用")
                    break;
                case 30002:
                    Debug.log("加载广告失败，重新加载广告")
                    break;
                default:
                    // 参考 https://minigame.vivo.com.cn/documents/#/lesson/open-ability/ad?id=广告错误码信息 对错误码做分类处理
                    Debug.log("banner广告展示失败")
                    Debug.log(JSON.stringify(err))
                    break;
            }
        });
    }
    private mHideTime: number = null!;
    private mMinHideInterval: number = 5
    public hideBanner() {
        Debug.log(MSG.HIDE_BANNER)

        if (!this.checkWindow()) return;
        let nowTime = Date.now();
        if (!this.mHideTime)
            this.mHideTime = nowTime;
        else if (this.mHideTime && nowTime - this.mHideTime <= this.mMinHideInterval * 1000) {
            Debug.log(`banner隐藏太频繁了 ${this.mMinHideInterval}秒内只隐藏一次`);
            return;
        }
        this.mHideTime = nowTime;
        if (this.mBannerAd && this.mBannerAd.hide) {
            Debug.log("隐藏和销毁banner")
            this.mBannerAd.hide();
            this.mBannerAd.offSize();
            this.mBannerAd.destroy();
            this.mBannerAd = null;
        }
    }
    private mVideoTime: number = null!;
    public createRewardAD(show: boolean, idIndex: number = 0) {
        if (this.videoLoading) {
            return;
        }
        if (!this.checkWindow()) {
            this.videoCb(VIDEO_STATUS.END);
            return;
        }
        if (!this.checkMethod("createRewardedVideoAd")) {
            return;
        }
        if (Common.isEmpty(this.getVideoId())) {
            console.warn(MSG.VIDEO_KEY_IS_NULL)
            return;
        }

        if (!this.mVideoTime) {
            this.mVideoTime = Date.now();
        }
        else {
            if (Date.now() - this.mVideoTime < 10 * 1000) {
                if (this.videoCb) {
                    this.videoCb(VIDEO_STATUS.ERR);
                }
                return;
            }
            else {
                this.mVideoTime = Date.now();
            }
        }
        let videoId = this.getVideoId(idIndex);
        if (!this.mVideo) {
            var win = this.getWindow();
            this.videoLoading = true;
            this.mVideo = win[this.platformName].createRewardedVideoAd({
                posId: videoId
            });
            this.mVideo.onError(this.onVideoError.bind(this));
            this.mVideo.onClose(this.onVideoClose.bind(this));
            this.mVideo.onLoad(this.onVideoLoad.bind(this));
        }
        else
            this.mVideo.load();

    }
    public onVideoLoad() {
        Debug.log(MSG.VIDEO_LOAD_COMPLETED)
        this.videoLoading = false;
        if (this.mVideo) {
            this.mVideo.show()
                .then(() => {
                    this.videoPlaying = true;
                    eventUtil.sendEventImmediately(EventConst.ON_PLATFORM_HIDE, {})
                    Debug.log('激励视频广告展示完成');
                }).catch((err: any) => {
                    Debug.log('激励视频广告展示失败', JSON.stringify(err));
                    if (this.videoCb) {
                        this.videoCb(VIDEO_STATUS.ERR);
                    }
                })
        }
    }
    public onVideoClose(isEnd: any) {
        Debug.log(MSG.VIDEO_CLOSE_COMPLETED, isEnd.isEnded)
        this.videoLoading = false;
        this.videoPlaying = false;
        if (!!isEnd.isEnded) {
            httpUtil.clickVideo();
        }
        eventUtil.sendEventImmediately(EventConst.ON_PLATFORM_SHOW, {})
        if (this.videoCb) {
            let ret = (!!isEnd.isEnded) ? VIDEO_STATUS.END : VIDEO_STATUS.NOTEND;
            this.videoCb(ret);
        }
    }
    public prepareInter() {
        if (Common.isEmpty(this.interId)) {
            console.warn(MSG.INTER_KEY_IS_NULL);
            return;
        }

        if (!this.checkWindow()) return;
        if (!this.checkMethod("createInterstitialAd")) return;

        var win = this.getWindow();
        if (this.inter) {
            this.inter.offLoad();
            this.inter.offClose();
            this.inter.offError();
            this.inter = null;
        }
        Debug.log('创建插屏广告');
        this.inter = win[this.platformName].createInterstitialAd({
            posId: this.interId
        });
        this.inter.onLoad(this._onInterLoad.bind(this));
        this.inter.onClose(this._onInterClose.bind(this));
        this.inter.onError(this._onInterError.bind(this));
        this.inter.load()
    };

    public showInter() {

        this.prepareInter();
    }
    public _onInterLoad() {
        if (this.inter) {
            let t = this.inter.show();
            t && t.then(() => {
                Debug.log('插屏广告展示完成');
            }).catch((err: any) => {
                Debug.log('插屏广告展示失败', err);
            })
        }
    }
    public _onInterOnShow() {
        if (this.inter)
            this.inter.load();
    }

    public showAutoBanner() {
        Debug.log(' vivo 不支持自动')
    }

    public reportMonitor(name: string, value: string) {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("reportMonitor")) return;
        var win = this.getWindow();
        win[this.platformName].reportMonitor('game_scene', 0)
    }


    private static lstCustomAd: { [index: number]: any } = {}
    private mCustomOnClose: any;

    public prepareNative(index: number = -1, isLoad: boolean = false) {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("createNativeAd")) return;
        var win = this.getWindow();

        this.destroyNative();
        var nativeGroup = this.GetRandomNativeGroup(platformConf.config.nativeList, NativeSize.LR, index);
        var posId = nativeGroup!.Id.trim();
        this.native = win[this.platformName].createNativeAd({
            posId: posId
        })
        this.native.onLoad(this._onNativeLoad);
        this.native.onError(this._onNativeError);
        this.native.onClose(this._onNativeClose);
        this.nativeLoading = true;
        if (isLoad)
            this.native.load();
    }

    public _onNativeLoad(res: any) {
        this.nativeLoading = false;
        Debug.log(MSG.NATIVE_LOAD_COMPLETED, res)
        if (res && res.adList && res.adList.length > 0) {
            let temp: Array<nativeAdResult> = [];
            res.adList.forEach((item: any, idx: number) => {
                temp.push({
                    ...item,
                    hasClick: idx > this.nativeAdResultList.length - 1 ? false : (this.nativeAdResultList[idx] as any).hasClick
                })
            })
            this.nativeAdResultList = temp;

            this.nativeAdResult = this.nativeAdResultList[this.nativeAdResultList.length - 1];
            if (!Common.isEmpty(this.nativeAdResult.adId)) {
                Debug.log(MSG.NATIVE_REPORT)
                this.native.reportAdShow({
                    adId: this.nativeAdResult.adId
                });
            }
            if (Common.isFunction(this.nativeCb)) {
                this.nativeCb(Common.deepCopy(this.nativeAdResult))
            }
        }
        else {
            Debug.log(MSG.NATIVE_LIST_NULL);
            this.nativeOnLoadCallback();
        }
    }

    public _onNativeError(err: any) {
        this.nativeLoading = false;
        if (err.code == 20003) {
            if (this.nativeIdIndex < platformConf.config.nativeList.length - 1) {
                Debug.log(MSG.NATIVE_ERROR, err)
                this.nativeIdIndex += 1;
                this.destroyNative();
            }
            else {
                Debug.log(MSG.NATIVE_NOT_ID_USE)
                this.nativeIdIndex = 0;
            }
        }
        else {
            Debug.log(MSG.NATIVE_ERROR2, err)
        }
        this.nativeOnLoadCallback();
    }
    public _onNativeClose() {

    }

    public nativeOnLoadCallback() {

        if (this.nativeCb) {
            let no_click_list = this.nativeAdResultList.filter((item: any) => !item.hasClick)
            if (no_click_list.length > 0) {
                Debug.log('选取第一个广告')
                this.nativeCb(no_click_list[0])
            }
            else {
                if (this.nativeAdResultList.length > 0) {
                    Debug.log('随机选取一个广告')
                    this.nativeCb(this.nativeAdResultList[Common.randomNumBoth(0, this.nativeAdResultList.length - 1)])
                }
                else
                    this.nativeCb(null);
            }
        }
    }

    public destroyNative() {
        this.nativeLoading = false;
        if (this.native) {
            this.native.offLoad(this._onNativeLoad) // 移除原生广告加载成功回调
            this.native.offError(this._onNativeError) // 移除失败回调
            this.native.destroy() // 隐藏 banner，成功回调 onHide, 出错的时候回调 onError
            this.native = null;
        }
        Debug.log(MSG.NATIVE_DESTROY)
    }

    /**
    * 目前只有OPPO VIVO 平台有此功能
    * 返回原生广告数据，开发者根据返回的数据来展现
    * 没有广告返回null
    * 
    * 
    * 例如 cocos
    * let adData=platformUtil.currentPlatform.getNativeAd();
    * cc.loader.load(adData.imgUrlList[0], (err, texture) => {
    *   adImg.active = true
    *   adImg.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(texture)
    * })
    * 
    * 例如 laya
    * let adData=platformUtil.currentPlatform.getNativeAd();
    * new Laya.Image().skin=adData.imgUrlList[0];
    * 
    * @param callback 回调函数
    */
    public showNativeAd(callback: Function) {
        this.nativeCb = callback;
        if (this.native) {
            let ret = this.native.load();
            ret && ret.then(() => {
                Debug.log('原生广告加载完成');
            }).catch((err: any) => {
                Debug.log('原生广告加载失败');

                this.nativeOnLoadCallback();
            })
        }
        else {
            this.prepareNative(-1, true);
            // if (this.native)
            //     this.native.load();
        }
    }
    public showNativePicAd(options: NativeOptions, index: number = -1, onClose: () => void, onError: () => void) {
        this.hideNativeLRAd();
        this.hideNativePicAd();
        var nativePicId = this.GetRandomNativeGroup(platformConf.config.nativeList, NativeSize.PIC, index);

        var sys = this.getSystemInfoSync();
        var style = options.GetStyle(sys);
        var win = this.getWindow();
        this.nativePic = win[this.platformName].createCustomAd({
            posId: nativePicId?.Id.trim(),
            style: style
        });
        this.nativePic.onError((err: any) => {
            Debug.log("nativeLR 原生模板广告加载失败", err);
            this.hideNativeLRAd();
        });
        this.nativePic.show().then(() => {
            Debug.log('nativeLR 原生模板广告展示完成');
        }).catch((err: any) => {
            Debug.log('nativeLR 原生模板广告展示失败', JSON.stringify(err));
        })

    }
    public hideNativePicAd() {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("createCustomAd")) return;
        var win = this.getWindow();
        if (win[this.platformName].createCustomAd) {
            if (this.nativePic) {
                Debug.log('nativePic destroy');
                this.nativePic.destroy();
                this.nativePic = null;
            }
        }
    }

    public showNativeLRAd(left = null, top = null, callback?: () => void) {
        let style = left && top ? { left: left, top: top } : null;
        if (!this.checkWindow()) return;
        if (!this.checkMethod("createCustomAd")) return;
        var win = this.getWindow();
        this.nativeLR = win[this.platformName].createCustomAd({
            posId: this.nativeLRId,
            style: style
        });
        this.nativeLR.onError((err: any) => {
            Debug.log("nativeLR 原生模板广告加载失败", err);
            this.hideNativeLRAd();
        });
        this.nativeLR.show().then(() => {
            Debug.log('nativeLR 原生模板广告展示完成');
        }).catch((err: any) => {
            Debug.log('nativeLR 原生模板广告展示失败', JSON.stringify(err));
        })
    }
    public hideNativeLRAd() {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("createCustomAd")) return;
        var win = this.getWindow();
        if (win[this.platformName].createCustomAd) {
            if (this.nativeLR) {
                Debug.log('nativeLR destroy');
                this.nativeLR.destroy();
                this.nativeLR = null;
            }
        }
    }
    /**
     * 目前只有OPPO平台有此功能 
     * 用户点击了展示原生广告的图片时，使用此方法
     * 例如 cocos
     * this.node.on(CocosNodeEvent.TOUCH_END, () => {
     *     platformUtil.currentPlatform.clickNative();
     * }, this)
     * 
     * 
     * 例如 laya
     * (new Laya.Image()).on(Laya.Event.MOUSE_UP, this, () => {
     *     platformUtil.currentPlatform.clickNative();
     * })
     * 
     */
    public clickNative(callback?: Function) {

        if (this.nativeAdResult && !Common.isEmpty(this.nativeAdResult.adId)) {
            this.mClickedNativeCallback = callback!;
            this.mIsClickedNative = true;
            Debug.log(MSG.NATIVE_CLICK, this.nativeAdResult.adId)
            this.native.reportAdClick({
                adId: this.nativeAdResult.adId
            })
            this.nativeAdResultList.forEach((item) => {
                if (item == this.nativeAdResult) {
                    (item as any).hasClick = true;
                }
            })
        }
    }
    private mClickedNativeCallback: Function = null!;
    private mIsClickedNative: boolean = false;
    private onAppShow() {
        if (this.mIsClickedNative) {
            this.mIsClickedNative = false;
            if (Common.isFunction(this.mClickedNativeCallback))
                this.mClickedNativeCallback();
        }
    }


    public hasShortcutInstalled(success: (has: boolean) => void, fail: (err: any) => void) {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("hasShortcutInstalled")) return;
        var win = this.getWindow();
        win[this.platformName].hasShortcutInstalled({
            success: (status: any) => {
                if (success)
                    success(!!status)
                if (status) {
                    Debug.log('已创建')
                } else {
                    Debug.log('未创建')
                }
            },
            fail: (res: any) => {
                if (fail)
                    fail(res)
            }
        })
    }
    public installShortcut(success: (res: any) => void, message: string = "方便下次快速启动", fail: (err: any) => void) {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("installShortcut")) return;
        var win = this.getWindow();
        win[this.platformName].installShortcut({
            message,
            success: (status: any) => {
                if (success)
                    success(status)
                Debug.log('创建成功')
            },
            fail: (res: any) => {
                if (fail)
                    fail(res)
            }
        })
    }

    public exitApplication() {
        if (!this.checkWindow()) return;
        if (!this.checkMethod("exitApplication")) return;
        var win = this.getWindow();
        win[this.platformName].exitApplication();
    }

    private onCloseGamePortalAd: () => void = null!;
    private onShowGamePortalAd: (success: boolean) => void = null!;
    public showBoxPortalAd(image: string, marginTop: number = 200, onClose?: () => void, onShow?: (success: boolean) => void) {

        if (!this.checkWindow()) {
            if (onShow)
                onShow(false);
            return;
        };
        var win = this.getWindow();
        if (!win[this.platformName].createBoxPortalAd) {
            if (onShow)
                onShow(false);
            return;
        };
        this.onCloseGamePortalAd = onClose!;
        this.onShowGamePortalAd = onShow!;
        let self = this;
        if (!this.gamePortalId) {
            console.warn('showGamePortalAd adUnitId 为空')
            return;
        }
        if (!this.gamePortalAd) {
            Debug.log('showGamePortalAd adUnitId :', this.gamePortalId)
            this.gamePortalAd = win[this.platformName].createBoxPortalAd({
                posId: this.gamePortalId,
                image: image,
                marginTop: marginTop
            })
            this.gamePortalAd.onClose(() => {
                Debug.log('close')
                if (this.gamePortalAd.isDestroyed) {
                    return
                }
                // 当九宫格关闭之后，再次展示Icon
                this.gamePortalAd.show();
                if (self.onCloseGamePortalAd && Common.isFunction(self.onCloseGamePortalAd))
                    self.onCloseGamePortalAd()
                Debug.log('互推盒子九宫格广告关闭')
            })
            this.gamePortalAd.onError((err: any) => {
                Debug.log('showGamePortalAd err', err)
                if (self.onShowGamePortalAd && Common.isFunction(self.onShowGamePortalAd))
                    self.onShowGamePortalAd(false);
            })
            this.gamePortalAd.onLoad(() => {
                Debug.log('互推盒子九宫格广告加载成功')
            })
            this.gamePortalAd.onShow(() => {
                Debug.log('showGamePortalAd onShow success')
                if (self.onShowGamePortalAd && Common.isFunction(self.onShowGamePortalAd))
                    self.onShowGamePortalAd(true);
            })

            this.gamePortalAd.show()
                .then(() => {
                    if (self.onShowGamePortalAd && Common.isFunction(self.onShowGamePortalAd))
                        self.onShowGamePortalAd(true);
                    Debug.log('showGamePortalAd success')
                }).catch((error: any) => {
                    if (self.onShowGamePortalAd && Common.isFunction(self.onShowGamePortalAd))
                        self.onShowGamePortalAd(false);
                    Debug.log('showGamePortalAd fail with:' + error.errCode + ',' + error.errMsg)
                })
        }
        else
            this.gamePortalAd.show()
                .then(() => {
                    Debug.log('load success')
                }).catch((error: any) => {
                    if (self.onShowGamePortalAd && Common.isFunction(self.onShowGamePortalAd))
                        self.onShowGamePortalAd(false);
                    Debug.log('load fail with:' + error.errCode + ',' + error.errMsg)
                })

    }

    public hideBoxPortalAd() {
        if (this.gamePortalAd != null) {
            this.gamePortalAd.hide()
            this.gamePortalAd.isDestroyed = true
            this.gamePortalAd.destroy();
            this.gamePortalAd = null;
        }
    }

}